#include "BlinnPhongShader.h"
#include "Constants.h"
#include "LambertianShader.h"
#include <algorithm>

using namespace std;

BlinnPhongShader::BlinnPhongShader(double& dR, double& dG, double& dB,
        double& sR, double& sG, double& sB, double& pExp, double& m) {
    surfaceColor.set(dR, dG, dB);
    specularColor.set(sR, sG, sB);
    phongExp = pExp;
    mirror = m;
}

cs5721::Vector3D BlinnPhongShader::calcColor(cs5721::Vector3D& intensity,
        cs5721::Vector3D& light, cs5721::Vector3D& normal, cs5721::Vector3D& view) {

    cs5721::Vector3D half = view + light;
    half.normalize();

    double maxNormalLight = max(0.0, normal.dot(light));
    double maxNormalHalf = max(0.0, normal.dot(half));

    double iR = intensity[0];
    double iG = intensity[1];
    double iB = intensity[2];

    //Lambertian shading
    double red = surfaceColor[0] * iR * maxNormalLight;
    double green = surfaceColor[1] * iG * maxNormalLight;
    double blue = surfaceColor[2] * iB * maxNormalLight;

    //BlinnPhong shading
    red += specularColor[0] * iR * pow(maxNormalHalf, phongExp);
    green += specularColor[1] * iG * pow(maxNormalHalf, phongExp);
    blue += specularColor[2] * iB * pow(maxNormalHalf, phongExp);

    cs5721::Vector3D color(red, green, blue);

    return color;
}

cs5721::Vector3D BlinnPhongShader::getSurfaceColor() {
    return surfaceColor;
}

double BlinnPhongShader::getMirrorCoef() {
    return mirror;
}